package jp.sourceforge.talisman.mds.distance;

/*
 * $Id: WardsClusterDistanceCalculator.java,v 1.1 2009/09/12 05:06:09 weiwei Exp $
 */

import jp.sourceforge.talisman.mds.Item;
import jp.sourceforge.talisman.mds.cluster.Cluster;

/**
 * 
 * @author Haruaki Tamada
 * @version $Revision: 1.1 $ 
 */
public class WardsClusterDistanceCalculator extends AbstractClusterDistanceCalculator{
    public WardsClusterDistanceCalculator(){
    }

    public WardsClusterDistanceCalculator(ItemDistanceAlgorithm ida){
        super(ida);
    }

    @Override
    public ClusterDistanceAlgorithm getAlgorithm(){
        return ClusterDistanceAlgorithm.WARDS_METHOD;
    }

    @Override
    public double calculate(Cluster c1, Cluster c2){
        Item pbar = c1.getMedian();
        Item qbar = c2.getMedian();

        double distance = getItemDistanceCalculator().calculate(pbar, qbar);

        return (c1.getSize() * c2.getSize() / (c1.getSize() + c2.getSize())) * distance;
    }

    @Override
    public double update(Cluster ci, Cluster cj, Cluster ck, double dij, double dik, double djk){
        int sum = ci.getSize() + cj.getSize() + ck.getSize();

        return dik * (ci.getSize() + ck.getSize()) / sum + djk * (cj.getSize() + ck.getSize()) / sum - dij * ck.getSize() / sum;
    }
}
